package com.kun.rental.utils;


import cn.hutool.core.date.DateTime;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.util.Date;
import java.util.Map;

/**
 * JWT工具类，提供JWT令牌的生成和解析功能。
 */
@Component
public class JwtUtils {
    /**
     * JWT的秘钥，用于签名和验证JWT令牌。
     */

    public static final String SECRET_KEY = "kun";
    /**
     * JWT令牌的过期时间，单位为毫秒。
     * 这里设置为30分钟。
     */
    public static final long EXPIRE_TIME = 1000L*60*30;

    /**
     * 创建一个JWT Token。
     * @param payload 包含Token有效载荷的Map，将被添加签发时间、过期时间和生效时间。
     * @return 生成的JWT Token字符串。
     */
    public static String createToken(Map<String, Object> payload){
        DateTime now=DateTime.now();
        DateTime newTime=new DateTime(now.getTime()+EXPIRE_TIME);
        // 设置Token的签发时间
        payload.put(JWTPayload.ISSUED_AT,now);
        // 设置Token的过期时间
        payload.put(JWTPayload.EXPIRES_AT,newTime);
        // 设置Token的生效时间，确保Token在签发后立即生效
        payload.put(JWTPayload.NOT_BEFORE,now);
        return JWTUtil.createToken(payload,SECRET_KEY.getBytes());
    }

    /**
     * 解析JWT Token并返回其Payload。
     *
     * @param token 待解析的JWT Token字符串。
     * @return 解析出的JWT Payload对象。
     * @throws RuntimeException 如果Token验证失败或已过期，则抛出异常。
     */
    public static JWTPayload parseToken(String token){
        JWT jwt = JWTUtil.parseToken(token); // 解析传入的token字符串
        if (!jwt.setKey(SECRET_KEY.getBytes()).verify()){ // 验证token的签名，确保token未被篡改
            throw new RuntimeException("token异常");
        }
        if (!jwt.validate(0)){ // 检查token是否过期
            throw new RuntimeException("token已过期");
        }
        return jwt.getPayload(); // 返回token的payload部分
    }

    //默认密钥
    public static final String DEFAULT_SECRET="mySecret";

    /**
     * 使用HMAC SHA-256签名算法
     * @param payloadStr 有效载荷
     * @param secret 密钥
     * @return JWS串
     */
    public static String generateTokenByHMAC(String payloadStr,String secret) throws JOSEException {
        //创建JWS头,设置签名算法和类型
        JWSHeader jwsHeader = new JWSHeader.Builder(JWSAlgorithm.HS256).type(JOSEObjectType.JWT).build();
        //将载荷信息封装到Payload中
        Payload payload = new Payload(payloadStr);
        //创建JWS对象
        JWSObject jwsObject = new JWSObject(jwsHeader, payload);
        //创建HMAC签名器
        JWSSigner jwsSigner = new MACSigner(secret);
        //签名
        jwsObject.sign(jwsSigner);
        return jwsObject.serialize();
    }

    /**
     * 验证签名,提取有效载荷,以PayloadDto对象形式返回
     * @param token JWS串
     * @param secret 密钥
     * @return PayloadDto对象
     */
//    public static PayloadDto verifyTokenByHMAC(String token, String secret) throws ParseException, JOSEException {
//        //从token中解析JWS对象
//        JWSObject jwsObject = JWSObject.parse(token);
//        //创建HMAC验证器
//        JWSVerifier jwsVerifier = new MACVerifier(secret);
//        if (!jwsObject.verify(jwsVerifier)) {
//            throw new JOSEException("token签名不合法!");
//        }
//        String payload = jwsObject.getPayload().toString();
//        PayloadDto payloadDto = JSONUtil.toBean(payload, PayloadDto.class);
//        if (payloadDto.getExp() < new Date().getTime()){
//            throw new JOSEException("token已过期!");
//        }
//        return payloadDto;
//    }

}

